package com.bytecodezz.app.base.framework.base.adapter

import android.content.Context
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.bytecodezz.app.base.extend.ui.onClick

/**
 * @author: bytecodezz
 * @version: 1.0
 * @time: 2021/7/8 12:56
 * @package: com.bytecodezz.app.base.framework.base.adapter
 *
 * @description:通用的RecyclerVie适配器
 *
 */
abstract class BaseAdapter<T> constructor(val context: Context, private val layoutId: Int) :
    RecyclerView.Adapter<BaseViewHolder>() {
    private val list: MutableList<T> by lazy { mutableListOf() }

    private var onItemClickListener: ((View, Int) -> Unit)? = null

    private var onItemLongClickListener: ((View, Int) -> Boolean)? = null

    fun setOnItemClickListener(itemClickListener: (View, Int) -> Unit) {
        onItemClickListener = itemClickListener
    }

    fun setOnItemLongClickListener(itemLongClickListener: (View, Int) -> Boolean) {
        onItemLongClickListener = itemLongClickListener
    }

    //运算符重载，让adapter对象可以直接使用 adapter[index] 获取到其中的item数据
    operator fun get(index: Int): T? {
        return list.getOrNull(index)
    }

    fun get(): List<T> = list

    protected open fun onCreateHolder(parent: ViewGroup, viewType: Int): BaseViewHolder? = null

    protected abstract fun convert(
        holder: BaseViewHolder,
        itemData: T,
        position: Int,
        payloads: List<T>
    )

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
        return onCreateHolder(parent, viewType) ?: BaseViewHolder(context, layoutId)
    }

    override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
        convert(holder, list[position], position, list)
        onItemClickListener?.let { itL ->
            holder.itemView.onClick {
                itL.invoke(holder.itemView, position)
            }
        }
        onItemLongClickListener?.let { itL ->
            holder.itemView.setOnLongClickListener {
                itL.invoke(holder.itemView, position)
            }
        }
    }

    override fun getItemCount(): Int = list.size

    fun refreshData(newData: List<T>) {
        this.list.clear()
        list.addAll(newData)
        this.notifyDataSetChanged()
    }

    fun appendData(newData: List<T>) {
        list.addAll(newData)
        this.notifyDataSetChanged()
    }

    fun insertData(index: Int, newData: List<T>) {
        if (index < 0 || index > list.size) {
            list.addAll(newData)
        } else {
            list.addAll(index, newData)
        }
        this.notifyDataSetChanged()
    }

    fun getItemData(position: Int): T = list[position]

}